package one.stand.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.vioao.wechat.api.TokenApi;
import com.github.vioao.wechat.bean.response.token.TokenResponse;
import one.stand.entity.ResultTemplateEntity;
import one.stand.enums.LoginEnum;
import one.stand.model.CompanyAccountModel;
import one.stand.model.WxNoticeModel;
import one.stand.request.CompanyAccountRequest;
import one.stand.service.CompanyAccontService;
import one.stand.service.WxMessageService;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;

/**
 * @author: QIK
 * @CreateDate: 2019/4/29 11:32
 */
@Service
public class WxMessageServiceImpl extends PublicBaseService implements WxMessageService {


    @Autowired
    private CompanyAccontService companyAccontService;

    /**
     * 得到用户端小程序token
     *
     * @return token
     */
    @Override
    public String getWxToken(String appId, String appSecret) {
        TokenResponse token= TokenApi.token(appId,appSecret);
        log.info("获取微信token:{}", JSON.toJSONString(token));
        return token.getAccessToken();
    }

    /**
     * 发送微信消息模板
     *
     * @parm touser 接收者（用户）的 openid
     * @parm formId 表单提交场景下，为 submit 事件带上的 formId；支付场景下，为本次支付的 prepay_id
     * @parm code 所需下发的模板消息的code
     * @parm fillData 数据型模板数据
     * @parm parameter 参数
     */

    @Override
    public void sendTemplate(String touser, String formId, Integer code, String[] fillData, String parameter, String accessToken,Integer companyId) {
        sendTemplateWx(touser, formId, code, fillData, parameter, accessToken, companyId);
    }

    @Override
    public void sendTemplate(String touser, String formId, Integer code, String[] fillData, String accessToken,Integer companyId) {
        sendTemplateWx(touser, formId, code, fillData, null, accessToken, companyId);
    }

    @Override
    @Async("asyncServiceExecutor")
    public String sendTemplateWx(String touser, String formId, Integer code, String[] fillData, String parameter, String accessToken, Integer companyId) {
        log.info("微信推送消息参数：{},{},{},{},{},{},{}",touser, formId, code, fillData, parameter, accessToken, companyId);
        if (StringUtils.isEmpty(formId) || StringUtils.isEmpty(touser) || null == code || companyId == null) {
            return null;
        }
        WxNoticeModel model = getWxNotice(code,companyId);
        if (model == null){
            return null;
        }
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost("https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + accessToken);
        // 装配post请求参数
        JSONObject json = new JSONObject();
        json.put("touser", touser);
        json.put("template_id", model.getValue());
        if (StringUtils.isEmpty(parameter)) {
            json.put("page", model.getPage());
        } else {
            json.put("page", model.getPage() + parameter);
        }
        json.put("form_id", formId);
        JSONObject dataJson = new JSONObject();
        for (int i = 0; i < fillData.length; i++) {
            JSONObject sonDateJson = new JSONObject();
            sonDateJson.put("value", fillData[i]);
            dataJson.put("keyword" + (i + 1), sonDateJson);
        }
        json.put("data", dataJson);
        String resultStr = "发送失败";
        try {
            StringEntity myEntity = new StringEntity(json.toJSONString(), ContentType.APPLICATION_JSON);
            // 设置post求情参数
            httpPost.setEntity(myEntity);
            HttpResponse httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                // 发送成功
                String resutlEntity = EntityUtils.toString(httpResponse.getEntity());
                log.info("推送结果：{}", resutlEntity);

                ResultTemplateEntity resultTemplateDate = JSONObject.parseObject(resutlEntity, ResultTemplateEntity.class);
                if ("40037".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "template_id不正确";
                }
                if ("41028".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "form_id不正确，或者过期";
                }
                if ("41029".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "form_id已被使用";
                }
                if ("41030".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "page不正确";
                }
                if ("45009".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "接口调用超过限额（目前默认每个帐号日调用限额为100万）";
                }
                if ("0".equals(resultTemplateDate.getErrcode())) {
                    resultStr = "成功";
                }
                log.info("本次微信推送模板推送结果：{}", resultStr);
                return resultTemplateDate.getErrcode();
            } else {
                // 发送失败
                return httpResponse.getStatusLine().getStatusCode() + "";
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpClient != null) {
                    // 释放资源
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            userMapper.delFormId(formId);
        }
        return resultStr;
    }

    public WxNoticeModel getWxNotice(Integer code, Integer companyId){
        if(code == null || companyId == null){
            return null;
        }
        return wxNoticeMapper.select(new WxNoticeModel(){{
            setCompanyId(companyId);
            setCode(code);
        }});
    }

    @Override
    public void sendTemplate(String touser, String formId, Integer code, String[] fillData, Integer accountType,Integer companyId) {
        String accessToken = accessToken(accountType, touser);
        log.info("模板推送-accessToken：{}", accessToken);
        if (StringUtils.isEmpty(accessToken)) {
            return;
        }
        sendTemplate(touser, formId, code, fillData, accessToken, companyId);
    }

    @Override
    public String sendTemplateWx(String touser, String formId, Integer code, String[] fillData, String parameter, Integer accountType, Integer companyId) {
        String accessToken = accessToken(accountType, touser);
        log.info("模板推送-accessToken：{}", accessToken);
        if (StringUtils.isEmpty(accessToken)) {
            return null;
        }

        return sendTemplateWx(touser, formId, code, fillData, parameter, accessToken, companyId);
    }

    @Override
    public void sendTemplate(String touser, String formId, Integer code, String[] fillData, String parameter, Integer accountType, Integer companyId) {
        String accessToken = accessToken(accountType, touser);
        log.info("模板推送-accessToken：{}", accessToken);
        if (StringUtils.isEmpty(accessToken)) {
            return;
        }
        sendTemplate(touser, formId, code, fillData, parameter, accessToken, companyId);
    }


    @Override
    public String accessToken(Integer accountType, Long userId) {
        CompanyAccountModel companyAccountModel = companyAccontService.selectByUserIdCopy(new CompanyAccountRequest() {{
            setUserId(userId);
            setAccountType(accountType);
        }});
        if (null == companyAccountModel) {
            log.info("获取微信账号信息失败：{}");
            return null;
        }
        String accessToken = getWxToken(companyAccountModel.getAppId(), companyAccountModel.getAppSecret());
        return accessToken;
    }

    public String accessToken(Integer accountType, String openId) {
        CompanyAccountModel companyAccountModel = companyAccontService.selectByUserIdCopy(new CompanyAccountRequest() {{
            if (accountType.equals(LoginEnum.CRM.getAccountType())) {
                setCrmOpenId(openId);
            }
            if (accountType.equals(LoginEnum.USER.getAccountType())) {
                setUserOpenId(openId);
            }
            setAccountType(accountType);
        }});
        if (null == companyAccountModel) {
            log.info("获取微信账号信息失败：{}");
            return null;
        }
        String accessToken = getWxToken(companyAccountModel.getAppId(), companyAccountModel.getAppSecret());
        return accessToken;
    }

    public void test(){


    }

}
